home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1995 / 6 / 02 / patch-work / patchopen.c < prev    next >
C/C++ Source or Header  |  1995-06-01  |  3KB  |  158 lines

  1. /*
  2. ** PatchOpen von Patrick Ohly
  3. ** Beispiel-Patch der Open-Funktion
  4. ** © 1994 Patrick Ohly
  5. */
  6.  
  7.  
  8. #ifdef _DCC
  9. #include <clib/exec_protos.h>
  10. #include <clib/dos_protos.h>
  11. #else
  12. #include <proto/exec.h>
  13. #include <proto/dos.h>
  14. #endif
  15. #include <clib/alib_protos.h>
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <exec/types.h>
  19. #include <exec/ports.h>
  20. #include <exec/semaphores.h>
  21. #include <dos/dos.h>
  22.  
  23. #include "PatchUtil.h"
  24.  
  25. #define PATCH_PORT "PatchDosOpen Port"
  26.  
  27. /* in amiga.lib enthalten */
  28. extern __far LONG LVOOpen;
  29.  
  30. /* CTRL-C-Handling unterdrücken */
  31. #ifdef _DCC
  32. void chkabort(void) { }
  33. #endif
  34.  
  35. /*
  36. ** Ausgabe über dieses FileHandle
  37. ** muß durch Semaphore geschuetzt werden.
  38. */
  39. struct SignalSemaphore FH_Sema;
  40. BPTR FH;
  41.  
  42. /*
  43. ** die vorherige Funktion
  44. ** !!! Achtung !!!
  45. ** Register A6 muß weiterhin einen Zeiger auf die
  46. ** jeweilige Library enthalten!
  47. ** Da der Compiler dies bei Zeigern auf die
  48. ** Funktionen nicht automatisch macht, muß ein
  49. ** weiteres Argument hinzugefügt werden!
  50. */
  51.  
  52. __regargs BPTR (* OldOpen)(__D1 char *name,
  53.                            __D2 LONG mode,
  54.             __A6 struct DosLibrary *DOSBase);
  55.  
  56. /* Anzahl der gerade aktiven Funktions-Aufrufe */
  57. WORD FunctionCounter = 0;
  58.  
  59. /*
  60. ** gibt bei jedem Aufruf von Open() Filename und
  61. ** Modus aus - verwendet dazu Standardausgabe
  62. */
  63. __regargs __geta4 __interrupt BPTR NewOpen(
  64.             __D1 char *name, __D2 LONG mode)
  65. {
  66.     char buffer[120];
  67.     BPTR fh;
  68.  
  69.     FunctionCounter++;
  70.  
  71.     sprintf(buffer, "\nFileName: %.68s\n"
  72.                    "Zugriff: ", name);
  73.     switch(mode)
  74.     {
  75.         case MODE_OLDFILE:
  76.             strcat(buffer, "MODE_OLDFILE\n");
  77.             break;
  78.         case MODE_NEWFILE:
  79.             strcat(buffer, "MODE_NEWFILE\n");
  80.             break;
  81.         case MODE_READWRITE:
  82.             strcat(buffer, "MODE_READWRITE\n");
  83.             break;
  84.         default:
  85.             strcat(buffer, "unbekannt\n");
  86.             break;
  87.     }
  88.  
  89.     /* vor Ausgabe Semaphore anfordern */
  90.     ObtainSemaphore(&FH_Sema);
  91.     Write(FH, buffer, strlen(buffer));
  92.     ReleaseSemaphore(&FH_Sema);
  93.  
  94.     /* Original-Funktion aufrufen und deren
  95.        Resultat zurückgeben                 */
  96.     fh = OldOpen(name, mode, DOSBase);
  97.     FunctionCounter--;
  98.     return(fh);
  99. }
  100.  
  101. int main(int argc, char **argv)
  102. {
  103.     struct MsgPort *msg_port;
  104.  
  105.     if(msg_port = FindPort(PATCH_PORT))
  106.     {
  107.         /* bereits installiertes PatchDosOpen
  108.            entfernen                          */
  109.         Signal(msg_port->mp_SigTask,
  110.                1L<<msg_port->mp_SigBit);
  111.         puts("Versuche bereits installiertes"
  112.              " PatchOpen zu entfernen...");
  113.     }
  114.     else
  115.     {
  116.         /* neu installieren
  117.            erzeuge öffentlichen Port */
  118.         if(msg_port = CreatePort(PATCH_PORT, 0))
  119.         {
  120.             APTR handle;
  121.  
  122.             InitSemaphore(&FH_Sema);
  123.             FH = Output();
  124.  
  125.             Forbid();
  126.             OldOpen = SafeSetFunction((struct Library *)DOSBase,
  127.                       (LONG)&LVOOpen, NewOpen,
  128.                       &handle);
  129.             Permit();
  130.  
  131.             if(OldOpen)
  132.             {
  133.                 puts("PatchOpen wurde installiert.");
  134.  
  135.                 /* warte auf Ctrl-C oder nochmaligen
  136.                    Start von PatchDosOpen            */
  137.                 Wait(SIGBREAKF_CTRL_C |
  138.                      1L<<msg_port->mp_SigBit);
  139.                 SetSignal(0, SIGBREAKF_CTRL_C);
  140.  
  141.                 RemoveFunction(OldOpen, handle);
  142.                 DeletePort(msg_port);
  143.  
  144.                 /* unsere Funktion steht nicht mehr im
  145.                    Vektor, aber andere Tasks könnten immer
  146.                    noch unseren Code benutzen
  147.                    => noch warten                       */
  148.                 do Delay(10);
  149.                 while(FunctionCounter);
  150.                 puts("PatchOpen wurde entfernt.");
  151.             }
  152.             else
  153.                 puts("Konnte Open() nicht patchen!");
  154.         }
  155.     }
  156.     return(0);
  157. }
  158.